package sk.sigp.aobot;

import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.io.IOUtils;

import sk.sigp.aobot.base.DetailedListener;
import sk.sigp.aobot.base.LoginListener;
import sk.sigp.aobot.client.BotCore;
import sk.sigp.aobot.client.core.Server;
import sk.sigp.aobot.swinggui.LoginFrame;
import sk.sigp.aobot.swinggui.MainFrame;
import bsh.EvalError;
import bsh.Interpreter;

/**
 * swing interaction gui for relay chat
 * 
 * @author Oest
 * 
 */
public class Connect implements LoginListener {
	
	private static Connect instance;

	public static Connect getInstance() {
		if (instance == null) {
			instance = new Connect();
		}
		return instance;
	}

	private MainFrame mainFrame;
	BotCore botCore;
	
	Interpreter script = new Interpreter();
	Timer timer = new Timer();
	Timer updateReactionTimer = new Timer();
	long reactionFileModified = -1;
	
	public BotCore getCore() {
		return botCore;
	}
	
	public MainFrame getMainFrame() {
		if (mainFrame==null) {
			mainFrame=new MainFrame(this);
		}
		return mainFrame;
	}
	
	public static void scriptMsgColor(String text, int color) {		
		getInstance().getMainFrame().sendMessage("<font color=\""+ Utils.colorToRgb(new Color(color)) +"\">"+text+"</font>",true);
	}
	
	public static void scriptMsg(String text) {
		getInstance().getMainFrame().sendMessage(text,true);
	}
	
	public static void scriptTell(String user, String text) {
		String textData = Utils.stringToHTMLString(text);
		getInstance().getMainFrame().messageRecieved("<font color=\""+Utils.chex(Colors.TELL_NAME)+"\">To <a href=\"cmdt" + user
				+ "\">"+user + "</a>: </font>" + textData);
		getInstance().getCore().sendMessageToUser(textData, user);
	}
	
	public static void scriptGroupTell(String group, String text) {
		String textData = Utils.stringToHTMLString(text);
		getInstance().getCore().sendMessageToGroup(textData, group);
	}

	/**
	 * responsible for running start script
	 */
	public void runStartScript() {
		try {
			File file = new File(Utils.DEFAULTS_PATH);
			if (file.exists()) {
				InputStream io = Connect.class.getClassLoader().getResourceAsStream("core.bsh");
				InputStream io2 = new FileInputStream(file);
				String scr = IOUtils.toString(io2);
				String sc = IOUtils.toString(io)+ scr + "\r\n return (Runnable) this;";
				Runnable result = (Runnable) script.eval( sc );
				result.run();
			} else 
				System.out.println("Defaults file couldnt be found");
		} catch (EvalError e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}		

	/**
	 * responsible for registering reaction script
	 */
	public void registerReactionScript() {
		try {
			File file = new File(Utils.REACTION_PATH);			
			if (file.exists()) {
				reactionFileModified = file.lastModified();				
				InputStream io = Connect.class.getClassLoader().getResourceAsStream("core.bsh");
				InputStream io2 = new FileInputStream(file);
				String scr = IOUtils.toString(io2);
				String sc = IOUtils.toString(io)+ scr + "\r\n return (DetailedListener) this;";
				DetailedListener result = (DetailedListener) script.eval( sc );
				
				if (getCore().getDetailedListeners().size()>0)
					getCore().getDetailedListeners().clear();
				
				getCore().getDetailedListeners().addListener(result);
				System.out.println("Reaction engine successfully reactivated");
			}
		} catch (EvalError e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}		
	
	public void logonInit(String login, String pwd, String nickName,
			Server server) {
		
		//make bot object
		try {
			botCore = new BotCore(
					nickName, 
					login, 
					pwd, 
					server
					);
		
			botCore.connect();
			
			registerReactionScript();
			
			//register mainframe as listener to chat core
			botCore.addListener(getMainFrame());	
			
			// ping once a while to keep connection
			timer.schedule(new TimerTask() {
				public void run() {
					botCore.ping();
				}
			}, 60000, 60000);
	
			//reaction script change check timer
			updateReactionTimer.schedule(new TimerTask() {
				public void run() {
					File file = new File(Utils.REACTION_PATH);
					if (file.exists()) {
						long lastTime = file.lastModified();
						if (lastTime>reactionFileModified) { 
							registerReactionScript();
							System.out.println("Reloading reaction script cos it was modified");
						}
					}
				}
			}, 1000,1000);
		} catch (IOException e) {
			getMainFrame().messageRecieved("Failed to connect "+login+" @ "+server.getName());
		}
		//show main frame
		getMainFrame().setVisible(true);
	}

	/**
	 * responsible for user run scripts
	 * @param scr
	 */
	public void runScript(String scr) {
		try {
			InputStream io = Connect.class.getClassLoader().getResourceAsStream("core.bsh");
			String sc = IOUtils.toString(io)+ scr + "\r\n return (Runnable) this;";
			Runnable result = (Runnable) script.eval( sc );
			result.run();
		} catch (EvalError e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}	
	
	public void showLoginFrame() {
		LoginFrame loginFrame = new LoginFrame();
		loginFrame.getListener().addListener(this);
		loginFrame.setVisible(true);
	}
	
	public static void main(String[] args) {
		Connect c = getInstance();
		c.runStartScript();
		c.showLoginFrame();
	}
}
